package com.ctbri.containerindepth;

class TwoTuple<A, B> implements Comparable<TwoTuple<A,B>>{
	public final A first;
	public final B second;

	public TwoTuple(A a, B b) {
		first = a;
		second = b;
	}

	public String toString() {
		return "(" + first + ", " + second + ")";
	}
	
	@Override
	public int hashCode() {
		int result = 17;
		if(first != null)
			result = 37 * result + first.hashCode();
		if(second != null)
			result = 37 * result + second.hashCode();
		return result;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof TwoTuple){
			TwoTuple<A, B> o = (TwoTuple<A,B>)obj;
			return (first == null ? o.first == null : first.equals(o.first))
				&& (second == null ? o.second == null : second.equals(o.second));
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public int compareTo(TwoTuple<A, B> o) {
		int res = ((Comparable<A>) first).compareTo(o.first);
		if(res != 0)
			return res;
		return ((Comparable<B>)second).compareTo(o.second);
	}
}

public class Tuple_Ex28 {
	public static <A, B> TwoTuple<A, B> tuple(A a, B b) {
		return new TwoTuple<A, B>(a, b);
	}

	/*public static <A, B, C> ThreeTuple<A, B, C> tuple(A a, B b, C c) {
		return new ThreeTuple<A, B, C>(a, b, c);
	}

	public static <A, B, C, D> FourTuple<A, B, C, D> tuple(A a, B b, C c, D d) {
		return new FourTuple<A, B, C, D>(a, b, c, d);
	}

	public static <A, B, C, D, E> FiveTuple<A, B, C, D, E> tuple(A a, B b, C c, D d, E e) {
		return new FiveTuple<A, B, C, D, E>(a, b, c, d, e);
	}*/
}
